/**
 * 文件上传：Stream模式、File模式
 * @link 官网参考地址：https://www.eggjs.org/zh-CN/basics/controller
 * @notice 为了保证文件上传的安全，框架限制了支持的文件格式。框架默认支持的白名单如下：
 * // images
 * '.jpg', '.jpeg', // image/jpeg
 * '.png', // image/png，image/x-png
 * '.gif', // image/gif
 * '.bmp', // image/bmp
 * '.wbmp', // image/vnd.wap.wbmp
 * '.webp',
 * '.tif',
 * '.psd',
 * // text
 * '.svg',
 * '.js', '.jsx',
 * '.json',
 * '.css', '.less',
 * '.html', '.htm',
 * '.xml',
 * // tar
 * '.zip',
 * '.gz', '.tgz', '.gzip',
 * // video
 * '.mp3',
 * '.mp4',
 * '.avi'
 */

const fs = require("fs/promises");
const path = require("path");
const sendToWormhole = require("stream-wormhole");

const Controller = require("egg").Controller;
module.exports = class UploadController extends Controller {
  // File模式：单文件上传
  async upload(ctx) {
    const file = ctx.request.files[0];
    const name = "egg-multipart-test/" + path.basename(file.filename);
    let result;
    try {
      // 处理文件，例如上传到云采存储
      result = await ctx.oss.put(name, file.filepath);
    } finally {
      // 注意删除临时文件
      await fs.unlink(file.filepath);
    }
    ctx.body = {
      url: result.url,
      // 获取全部字段值
      requestBody: ctx.request.body,
    };
  }
  // File模式：多文件上传
  async uploads() {
    const { ctx } = this;
    console.log(ctx.request.body);
    console.log(`共收到 ${ctx.request.files.length} 个文件`);
    for (const file of ctx.request.files) {
      console.log(`字段名: ${file.fieldname}`);
      console.log(`文件名: ${file.filename}`);
      console.log(`编码: ${file.encoding}`);
      console.log(`MIME 类型: ${file.mime}`);
      console.log(`临时文件路径: ${file.filepath}`);
      let result;
      try {
        // 处理文件，例如上传到云采存储
        result = await ctx.oss.put("egg-multipart-test/" + file.filename, file.filepath);
      } finally {
        // 注意删除临时文件
        await fs.unlink(file.filepath);
      }
      console.log(result);
    }
  }
  // Stream 模式 上传
  async uploader() {
    const ctx = this.ctx;
    const parts = ctx.multipart();
    let part;
    // parts() 返回 promise 对象
    while ((part = await parts()) != null) {
      if (part.length) {
        // 这是 busboy 的字段
        console.log("field：" + part[0]);
        console.log("value：" + part[1]);
        console.log("valueTruncated：" + part[2]);
        console.log("fieldnameTruncated：" + part[3]);
      } else {
        if (!part.filename) {
          // 这时是用户没有选择文件就点击了上传（part 是 file stream，但是 part.filename 为空）
          // 需要做出处理，例如给出错误提示消息
          return;
        }
        // part 是上传的文件流
        console.log("field：" + part.fieldname);
        console.log("filename：" + part.filename);
        console.log("encoding：" + part.encoding);
        console.log("mime：" + part.mime);
        // 文件处理，上传到云存储等等
        let result;
        try {
          result = await ctx.oss.put("egg-multipart-test/" + part.filename, part);
        } catch (err) {
          // 必须将上传的文件流消费掉，要不然浏览器响应会卡死
          await sendToWormhole(part);
          throw err;
        }
        console.log(result);
      }
    }
    console.log("and we are done parsing the form!");
  }
};
